package com.shengwei.truck.driver.view.ui;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProviders;
import com.google.gson.JsonSyntaxException;
import com.shengwei.truck.driver.R;
import com.shengwei.truck.driver.utils.MyToast;
import com.shengwei.truck.driver.view.ui.app.MyApplication;
import com.shengwei.truck.driver.vm.ViewModelFactory;
import com.shengwei.truck.driver.bean.Result;
import com.shengwei.truck.driver.bean.User;
import com.shengwei.truck.driver.model.DataSource;
import com.shengwei.truck.driver.net.NetWorkUtils;
import com.shengwei.truck.driver.utils.MyLogCat;
import com.shengwei.truck.driver.utils.StatusBarUtil;
import com.shengwei.truck.driver.view.selfview.CustomProgress;
import com.shengwei.truck.driver.view.ui.mine.userinfo.LoginActivity;
import com.shengwei.truck.driver.vm.LoginViewModel;

import java.lang.ref.WeakReference;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
/**
 * Activity基类，在各子类Activity里需要重复写的代码，统一都放在这里，通过继承此基类重用这些代码
 */
public abstract class BaseActivity<VM extends ViewModel,VDB extends ViewDataBinding> extends AppCompatActivity {
    protected VM mViewModel;
    protected VDB mDataBinding;
    private CustomProgress dialog;
    protected Toolbar mToolbar;
    String TAG = "BaseActivity";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityCollectorUtil.addActivity(this);
        //实例化布局文件对象(dataBindingLogin)
        mDataBinding = DataBindingUtil.setContentView(this,getContentViewId());
        StatusBarUtil.setStatusBarLightMode(this, Color.WHITE);
        //创建每一个Activity对应的ViewModel
        createViewModel();
        addLifeCycleObserver();
        mToolbar = this.findViewById(R.id.toolbar);
        setToolBar(true,true,this.getTitle().toString());
    }
    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onDestroy() {
        ActivityCollectorUtil.removeActivity(this);
        super.onDestroy();
    }

    /**
     * 根据泛型类的第一个参数VM传递过来的具体类型，new出这个具体类型的viewModel
     * 如new出 loginViewModel 与 HomeViewModel
     */
    public void createViewModel()
    {
        if(mViewModel == null) {
            Class myViewModelClass;
            Type type = getClass().getGenericSuperclass();
            if(type instanceof ParameterizedType) {
                myViewModelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[0];
            }
            else {
                myViewModelClass = AndroidViewModel.class;
            }

            if (myViewModelClass.isAssignableFrom(LoginViewModel.class)) { //登录ViewModel特殊些，也使用context
                //生成VM层实例，其中Repository+DataSource共同构成了M层。
                mViewModel = (VM)ViewModelProviders.of(this, new ViewModelFactory((MyApplication) getApplication())).get(myViewModelClass);
            }
            else {
                mViewModel = (VM)ViewModelProviders.of(this).get(myViewModelClass);
            }

        }
        return;
    }

    /**
     * 封装了请求接口过程中，当处于各种状态时，做出的处理，如显示与隐藏加载框的时机等。
     * 其中 “成功状态” 时的回调处理函数 单独实现在Activity页面里，因为要使用成功时返回的数据。
     * @param <T>
     */
    public abstract class OnCallback<T> implements Result.OnHandleCallback<T> {
        @Override
        public void onLoading(String msg) {
            if (dialog == null) {
                dialog = CustomProgress.show(BaseActivity.this, "", true, null);
            }
            if (!TextUtils.isEmpty(msg)) {
                dialog.setMessage(msg);
            }
            if (!dialog.isShowing()) {
                dialog.show();
            }
        }

        @Override
        public void onError(Throwable throwable) {
            MyLogCat.i(TAG,"onError postFile"+throwable.getMessage());
            WeakReference<Context> contextWeakReference = new WeakReference<>(getApplicationContext());
            if (!NetWorkUtils.isNetworkConnected(getApplicationContext())) {
                MyToast.showToastCenter(contextWeakReference,getResources().getString(R.string.result_network_error), Toast.LENGTH_SHORT,true);
                return;
            }
            if (throwable instanceof ConnectException) {
                MyToast.showToastCenter(contextWeakReference,getResources().getString(R.string.result_server_error),Toast.LENGTH_SHORT,true);
            } else if (throwable instanceof SocketTimeoutException) {
                MyToast.showToastCenter(contextWeakReference,getResources().getString(R.string.result_server_timeout),Toast.LENGTH_SHORT,true);
            } else if (throwable instanceof JsonSyntaxException) {
                MyToast.showToastCenter(contextWeakReference,getResources().getString(R.string.parse_error),Toast.LENGTH_SHORT,true);
            } else {
                MyToast.showToastCenter(contextWeakReference,getResources().getString(R.string.result_empty_error),Toast.LENGTH_SHORT,true);
            }
            dismissDlg();
        }

        @Override
        public void onFailure(String msg) {
            dismissDlg();

            if(msg != null){
                MyLogCat.i(TAG,msg);
                String[] errMsg = msg.split(";");
                int code = Integer.parseInt(errMsg[0]);
                String tip = errMsg[1];
                WeakReference<Context> contextWeakReference =  new WeakReference<>(getApplicationContext());
                MyToast.showToastCenter(contextWeakReference,tip,Toast.LENGTH_SHORT,true);
                //401,token过时; 403没有权限
                if(code == 401 || code == 403) {
                    User user = User.getInstance(getApplicationContext());
                    user.setToken("");
                    Intent i = new Intent(BaseActivity.this, LoginActivity.class);
                    startActivity(i);
                }
            }
        }
        @Override
        public void onCompleted() {
            dismissDlg();
        }
        @Override
        public void onProgress(int precent, long total) {
        }

        /**
         * 请求网络取消了
         */
        @Override
        public void onCancel() {
            dismissDlg();
        }
    }

    public void dismissDlg() {
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
        }
    }

     protected abstract int getContentViewId();

    /**
     *
      让DataSource能感知Activity的生命周期，在Activity.onstop的时候，DataSource中的某些函数会自动执行,
      这里用到的正是Android JetPack架构组件中的 “LifeCycle”.
    */
    protected  void addLifeCycleObserver() {

        getLifecycle().addObserver(DataSource.getSingleInstance());
    }

    /**
     * 配置页面标题栏,这里
     */
    public void setToolBar(boolean isSHowBack,boolean isDisplayTitle,String titleResId)
    {
        if(mToolbar != null) {
            setSupportActionBar(mToolbar);
            ActionBar actionBar = getSupportActionBar();
            setToolbarBack(actionBar,isSHowBack);


            //自定义标题显示
            if(isDisplayTitle) {
                actionBar.setDisplayShowTitleEnabled(true);
                actionBar.setTitle(titleResId);
        /*       TextView tvTtile =  mToolbar.findViewById(R.id.tvTitle);
               tvTtile.setText(titleResId);*/
            }
            else{
                actionBar.setDisplayShowTitleEnabled(false);
              //  mToolbar.findViewById(R.id.tvTitle).setVisibility(View.GONE);
            }
        }
    }

    /**
     * 设置actionbar的title
     * @param titleResId: 标题字符串ID
     */
    public void setTitle(int titleResId) {
        getSupportActionBar().setTitle(titleResId);
    }

    /**
     * 设置Toolbar是否显示返回键
     * @param actionBar
     * @param isShowBack
     */
    public void setToolbarBack(ActionBar actionBar,boolean isShowBack)
    {
        actionBar.setDisplayHomeAsUpEnabled(isShowBack);
        Drawable backDrawable = this.getDrawable(R.drawable.icon_back_left);
        actionBar.setHomeAsUpIndicator(backDrawable);;
        if(isShowBack) {
            setBackClick();
        }
    }
    public void setBackClick() {
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}